Test cases for Perspectives Server code. Feel free to add more!

Each utility module can be unit-tested on its own as well.
Tests that can be tested automatically by the unit test modules are marked with '(A)'
(see the modules in the /test directory and their '-h' usage statements for details).

-------


- Does the server start up?
	- Even in a hosted environment where cherrypy can't rely on the PORT?
- Does it automatically create a private key if none exists?
- Does it connect to the database?
	- sqlite
	- postgresql
- Does it automatically create tables if none exist?


Arguments
---------
--webport and --envport
	- If neither is specifed do we use the default port?
	- If webport is specefied but is not an integer, does argparse reject it?
	- If webport is specified and is an integer, and no envport is given, do we use the webport?
	- If envport is specified but no environment variable by that name exists, do we throw a ValueError?
	- If envport is specified and the env var exists but is not an integer, do we throw a ValueError?
	- If envport is specified and the env var exists and is a valid integer, do we use it?
	- If both are specified, does argparse reject that usage?

--cache-duration
	- Are negative numbers and non-integers rejected?
	- Are arguments with letters from more than one of the groups [Ss], [Mm], and [Hh] rejected?
	- Are the seconds, minutes, and hours calculated correctly for each letter group?
	- Are hours used by default if there are no letters specified?


While Running:
--------------
- If we get a request for an unknown service, does the server spawn a query process to ask about it?
	- Do only a limited number of process spawn, even across threads?
	- Does a process not start up if another process is already querying that service?
	- Are the results properly reported back to the database?
- If we have data do we display the results?
	- Including multiple keys for a given service?
- If the visitor simply goes to the index do they get the HTML explanation page?
	- Are the public key and version number displayed?
	- Is the metric on/off status displayed on the page?
	- Is the SNI scan on/off status displayed on the page?
	- Do the HTML and CSS validate properly? e.g. with:
		http://validator.w3.org/
		http://jigsaw.w3.org/css-validator/
	- Do the HTML and CSS display properly when a Content Security Policy is applied?
- If the service_type is unknown do they get a 400 error?
- If any extra, unknown parameters are passed does the server raise a 400 error?
- Does the favicon work?
- If enabled, are metrics properly logged to the database for each type of event?
	- If enabled, are they properly printed to the log?


Database Connections:
---------------------
How to count connections for various database types:

	postgres:
		select numbackends from pg_stat_database WHERE datname = 'dbname'


- When retrieving observations for a known service, are the database connections properly closed afterward?
	- When scanning for a new service?


Database Transactions:
----------------------
- (A) Does the database throw an error if we try to insert an observation with a start time < 0?
- (A) Does the database throw an error if we try to insert an observation with an end time < 0?
- (A) Does the database throw an error if we try to insert an observation with an end time < the start time?
	- (A) Does the code check for these conditions as well, in case they cannot be enforced by the database?


Failing Gracefully:
-------------------
- If the server can't connect to the database, does it still log an error and attempt to serve data from the cache?
	- Does the static index page still get created?
- If both the cache and database are unavailable will the server log errors, serve an HTTP 503 code, and keep running?
- Does the database fail gracefully if it does not have permission to create tables?
- Does the database fail gracefully if it does not have INSERT permission in the database? :
	- For Observations and Services, does it log an error and attempt to continue (instead of crashing)?
	- For Machines, and Event Types (on startup) does it log an error, disable database metrics, and continue?
	- For Metrics does it ignore the metric, log an error, and continue?
- Are metrics throttled back if the server receives many requests in a short period of time? (e.g. 200 requests per second)


In-memory caching with pycache:
-------------------------------
- (A) If the cache is below the memory limit, are new keys continually added upon request?
- If adding a new key would use too much memory, does the cache remove an entry and then store the key?
	- Is the least recently used entry removed?
	- If removing one entry doesn't clear enough RAM, does the cache remove multiple entries until it has enough space?
	- Do both the hash and the heap size go down?
- (A) If a requested object is bigger than total RAM allowed, do we log a warning and not store it?
- When an existing entry is retrieved from the cache is it's 'last viewed' time updated?

expiry:
- (A) Are expired entries removed during get() calls and None returned instead?
- Are expired entries cleaned up as they are encountered when clearing new memory?
- (A) Are non-positive expiry times rejected and cache entries not created?

pycache threads:
- Do we only create a single cache and return the proper results regardless of how many threads the server uses?
- If multiple threads attempt to set a value for the same key is only one of them allowed to set and the rest return immediately?
- If multiple threads attempt to set a value for *different* keys, are they all allowed to do so?
- Is only one thread at a time allowed to adjust the current memory usage?

pycache arguments:
- Are characters other than 0-9MGB rejected, throwing an error?
- Does it stop you from specifyng MB *and* GB?
- Is it case insensitive?
- Does the cache have to be at least 1MB?


Admin Shell Scripts
-------------------
- Does the setup script create the logs directory?
- Does the setup script properly add the cron entries to crontab?
	- Are existing crontab entries left untouched?
	- Does running the setup script multiple times not damage the crontab list?

- Can you start and stop the webserver when nothing else is running?
	- From any directory?
	- Are stderr and stdout properly sent to the logfile?
- Can you start and stop the scanning process when nothing else is running?
	- From any directory?
	- Are stderr and stdout properly sent to the logfile?

- Can you start and stop the webserver when the scanner is already running?
	- Is the scan process left alone?
- Can you start and stop the scan process when the webserver is already running?
	- Is the webserver process left alone?

- Does the webserver start when the machine reboots?
- If the webserver stops (e.g. due to an error) does it start again at the next five minute clock interval (i.e. does the crontab job start it again)?

- Does the restart script restart the webserver?
	- Does it leave the scan process alone?

